/******************************************************************************
** 公司名称：天津柯迪斯科技有限公司
** 版权信息：
** 文件名称： bsp_CAN.c
** 模块名称： KD186-CAN板级外设CAN模块初始化
** 版 本 号： V1.0
** 作    者： 蒲磊
**
** 修改记录： 版本     修改人      时间         修改内容
**
******************************************************************************/

/******************************************************************************
* 头文件
******************************************************************************/
#include "bsp_CAN.h"
#include "App_Protocol.h"
/******************************************************************************
* 宏定义
******************************************************************************/

/******************************************************************************
* 类型定义
******************************************************************************/

/******************************************************************************
* 函数声明
******************************************************************************/

/******************************************************************************
* 全局变量定义
******************************************************************************/

/*****************************************************************************
* 函数实现
******************************************************************************/


/******************************************************************************
** 功  能：外设初始化
** 参  数：无
** 返回值：无
** 备  注：
******************************************************************************/
void vbsp_CAN_Init(void)
{
    gpio_init_type gpio_init_struct;
    can_base_type can_base_struct;
    can_baudrate_type can_baudrate_struct;
    can_filter_init_type can_filter_init_struct;

    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);


    gpio_default_para_init(&gpio_init_struct);
    /* can tx pin PA12*/
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_12;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &gpio_init_struct);
    /* can rx pin PA11*/
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_pins = GPIO_PINS_11;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOA, &gpio_init_struct);

    /* can base init */
    can_default_para_init(&can_base_struct);
    can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
    can_base_struct.ttc_enable = FALSE;
    can_base_struct.aebo_enable = TRUE;
    can_base_struct.aed_enable = TRUE;
    can_base_struct.prsf_enable = FALSE;
    can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
    can_base_struct.mmssr_selection = CAN_SENDING_BY_ID;
    can_base_init(CAN1, &can_base_struct);

    /* 72M/36/(7+8+1)=125000,72M/18/(7+8+1)=250000*/
    can_baudrate_struct.baudrate_div = 18;
    can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ;
    can_baudrate_struct.bts1_size = CAN_BTS1_8TQ;
    can_baudrate_struct.bts2_size = CAN_BTS2_7TQ;
    can_baudrate_set(CAN1, &can_baudrate_struct);

    /*CAN过滤器0初始化,一开始设置为允许所有帧通过。后续根据协议再设置过滤器*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 1;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = 0x0000;
    can_filter_init_struct.filter_id_low = 0x0000;
    can_filter_init_struct.filter_mask_high = 0x0000;
    can_filter_init_struct.filter_mask_low = 0x0000;
    can_filter_init(CAN1, &can_filter_init_struct);



    /* can interrupt config */
    //nvic_irq_enable(CAN1_SE_IRQn, 0x01, 0x00);
    nvic_irq_enable(CAN1_RX0_IRQn, 0x03, 0x00);
    can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
    //can_interrupt_enable(CAN1, CAN_ETRIEN_INT, TRUE);
    //can_interrupt_enable(CAN1, CAN_EOIEN_INT, TRUE);
}
/******************************************************************************
** 功  能：设置八方CAN协议用的过滤器
** 参  数：无
** 返回值：无
** 备  注：
******************************************************************************/
void vbsp_CAN_Set_BF_Filter(void)
{
    can_filter_init_type can_filter_init_struct;

    /*CAN过滤器0初始化,设置为只允许目标ID为0x03（仪表）的帧通过*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 1;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = 0x00C0;
    can_filter_init_struct.filter_id_low = 0x0000;
    can_filter_init_struct.filter_mask_high = 0x07C0;
    can_filter_init_struct.filter_mask_low = 0x0000;
    can_filter_init(CAN1, &can_filter_init_struct);

    /*CAN过滤器1初始化,设置为只允许索引为0x32（控制器）的帧通过*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 2;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = 0x0001;
    can_filter_init_struct.filter_id_low = 0x9000;
    can_filter_init_struct.filter_mask_high = 0x0007;
    can_filter_init_struct.filter_mask_low = 0xF800;
    can_filter_init(CAN1, &can_filter_init_struct);

    /*过滤器组2设置，设置为只允许索引为0x34（电池）的帧通过*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 3;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = 0x0001;
    can_filter_init_struct.filter_id_low = 0xA000;
    can_filter_init_struct.filter_mask_high = 0x0007;
    can_filter_init_struct.filter_mask_low = 0xF800;
    can_filter_init(CAN1, &can_filter_init_struct);

    /*过滤器组3设置，设置为只允许状态码为111（报警数据）的帧通过*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 4;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = 0x0038;
    can_filter_init_struct.filter_id_low = 0x0000;
    can_filter_init_struct.filter_mask_high = 0x0038;
    can_filter_init_struct.filter_mask_low = 0x0000;
    can_filter_init(CAN1, &can_filter_init_struct);

    /*过滤器组4设置，只允许工厂指令的帧通过*/
    can_filter_init_struct.filter_activate_enable = TRUE;
    can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
    can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
    can_filter_init_struct.filter_number = 5;
    can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
    can_filter_init_struct.filter_id_high = (0x1F000000UL << 3) >> 16;
    can_filter_init_struct.filter_id_low = (uint16_t)(0x1F000000UL << 3);
    can_filter_init_struct.filter_mask_high = 0xFFF0;
    can_filter_init_struct.filter_mask_low = 0x0000;
    can_filter_init(CAN1, &can_filter_init_struct);

}


/******************************************************************************
** 功  能：Can中断函数
** 参  数：
** 返回值：无
** 备  注：
******************************************************************************/
void CAN1_RX0_IRQHandler(void)
{
    can_rx_message_type     CanRxData;

    can_message_receive(CAN1,CAN_RX_FIFO0,&CanRxData);
    if(CanRxData.id_type == CAN_ID_EXTENDED)
    {
        vPROTOCOL_CanMsgToProtocolMsg(&CanRxData);
    }


}

